package cn.edu.njuit.springbootfilmreview.controller;

import cn.edu.njuit.springbootfilmreview.dto.AccountInfo;
import cn.edu.njuit.springbootfilmreview.dto.ValidateCode;
import cn.edu.njuit.springbootfilmreview.service.AccountInfoService;
import cn.edu.njuit.springbootfilmreview.service.impl.UserTokenService;
import cn.edu.njuit.springbootfilmreview.service.impl.ValidateCodeService;
import cn.edu.njuit.springbootfilmreview.utils.Result;
import cn.edu.njuit.web.server.tools.ImageTool;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import static cn.edu.njuit.springbootfilmreview.utils.ResultCode.*;


/**
 * @Author guzy
 * @Description 账户接口层
 * @Date 2022/5/23 14:52
 **/

@RestController
@RequestMapping("")
@Api(value = "账户接口", tags = "账户接口")
public class AccountInfoController {

    @Autowired
    AccountInfoService accountInfoService;

    @Autowired
    ValidateCodeService validateCodeService;

    @Autowired
    UserTokenService userTokenService;

    @ApiOperation(value = "注册")
    @PostMapping("/api/registered")
    public Result registered(@RequestBody AccountInfo accountInfo) {
        if (accountInfo.getUsername() == null
                || accountInfo.getUsername() == ""
                || accountInfo.getPassword() == null
                || accountInfo.getPassword() == "") {
            return Result.failure(PARAM_IS_BLANK);
        } else {
            List<AccountInfo> accountSByUserName = accountInfoService.getAccountSByUserName(accountInfo.getUsername());
            //判断 用户名是否存在
            if (accountSByUserName.size() > 0) {
                return Result.failure(USER_IS_EXIST);
            } else {
                //不存在 就注册
                AccountInfo accountInfo1 = accountInfoService.insertAccountInfo(accountInfo);
                if (accountInfo1 != null) {
                    return Result.success(accountInfo1);
                } else {
                    return Result.failure(USER_SIGN_UP_FAIL);
                }
            }
        }

    }


    @ApiOperation(value = "获取验证码")
    @GetMapping("/api/validate-code")
    public Result getValidateCode() {
        ValidateCode validateCode = validateCodeService.createValidate();
        return Result.success(validateCode);
    }


    @ApiImplicitParam(value = "随机码", name = "code", dataType = "String", required = true)
    @ApiOperation(value = "获取验证码照片")
    @GetMapping("/image/validate-code/{code}")
    public ResponseEntity getValidateCodeImage(@PathVariable String code) throws IOException {
        if (code == null) {
            //alibaba json
            JSONObject error = new JSONObject();
            error.put("errorMessage", "参数缺失");
            return ResponseEntity.internalServerError().body(error);
        } else {
            String imageText = validateCodeService.getValidateText(code);
            //调用字符串生成图片的方法
            ImageTool imageTool = new ImageTool();
            Integer width = imageText.length() * 16;
            Integer height = 40;
            ByteArrayOutputStream image = imageTool.string2Image(imageText, width, height);

            return ResponseEntity
                    .status(HttpStatus.OK)
                    .contentType(MediaType.IMAGE_JPEG)
                    .body(image.toByteArray());
        }
    }

    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户名", name = "username", dataType = "String", required = true),
            @ApiImplicitParam(value = "密码", name = "password", dataType = "String", required = true),
            @ApiImplicitParam(value = "随机码", name = "randomCode", dataType = "String", required = true),
            @ApiImplicitParam(value = "验证码", name = "validateCode", dataType = "int", required = true)}
    )
    @ApiOperation(value = "登录")
    @PostMapping("api/login")
    public Result login(@RequestParam String username,
                        @RequestParam String password,
                        @RequestParam String randomCode,
                        @RequestParam Integer validateCode) {
        //判断是否缺少参数
        if (username != null && password != null && randomCode != null && validateCode != null) {
            //将获取的用户名和密码生成对象
            AccountInfo accountInfo = new AccountInfo(username, password);
            boolean loginFlag = accountInfoService.isLogin(accountInfo);
            //先判断是否已经被封号了
            if (loginFlag) {
                return Result.failure(USER_ACCOUNT_FORBIDDEN);
            }
            //将 验证码和随机码  进行校验  如果返回是对的就通过
            boolean codeIsTrue = validateCodeService.validate(randomCode, String.valueOf(validateCode));
            if (!codeIsTrue) {
                return Result.failure(USER_VERIFY_CODE_ERROR);
            }
            //将用户名和密码进行校验
            boolean loginValidateFlag = accountInfoService.loginValidate(accountInfo);
            if (!loginValidateFlag) {
                return Result.failure(USER_ACCOUNT_OR_PASSWORD_ERROR);
            }
            //已登录修改status状态
            accountInfoService.updateAccountInfoStatusISFalse(accountInfo.getId());
            //登录成功
            //生成token
            String token = userTokenService.getToken(username);
            JSONObject result = new JSONObject();
            result.put("token", token);
            return Result.success(result);
        } else {
            return Result.failure(PARAM_NOT_COMPLETE);
        }
    }


    @ApiImplicitParam(value = "账户唯一id", name = "id", dataType = "Long", required = true)
    @ApiOperation(value = "退出，修改账户状态")
    @PostMapping("api/layout")
    public Result layoutAccount(@RequestParam Long id) {
        boolean b = accountInfoService.updateAccountInfoStatusISTure(id);
        if (b) {
            return Result.success("退出成功");
        } else {
            return Result.failure(RESULT_CODE_DATA_NONE);
        }
    }

    @ApiImplicitParam(value = "用户唯一id", name = "id", dataType = "Long", required = true)
    @ApiOperation(value = "根据用户id获取用户信息")
    @GetMapping("api/login/getAccountById")
    public Result getAccountInfoById(@RequestParam Long id) {
        AccountInfo accountById = accountInfoService.getAccountById(id);
        if (accountById != null) {
            return Result.success(accountById);
        } else {
            return Result.failure(RESULT_CODE_DATA_NONE);
        }
    }


    @ApiImplicitParam(value = "登录令牌", name = "tokenString", dataType = "String", required = true)
    @ApiOperation(value = "根据token获取用户信息")
    @GetMapping("api/login/getAccountByToken")
    public Result getAccountInfoByToken(@RequestParam String tokenString) {
        AccountInfo user = userTokenService.getUser(tokenString);
        if (user != null) {
            return Result.success(user);
        } else {
            return Result.failure(RESULT_CODE_DATA_NONE);
        }
    }

    @ApiImplicitParam(value = "用户名", name = "username", dataType = "String", required = true)
    @ApiOperation(value = "根据username获取用户信息")
    @GetMapping("api/login/getAccountByUsername")
    public Result getAccountInfoByUserName(@RequestParam String username) {
        AccountInfo accountByUserName = accountInfoService.getAccountByUserName(username);
        if (accountByUserName != null) {
            return Result.success(accountByUserName);
        } else {
            return Result.failure(RESULT_CODE_DATA_NONE);
        }
    }
}
